#ifndef LOCKER_H
#define LOCKER_H

#include <exception>//标准库组件抛出的各种异常的基类
#include <pthread.h>
#include <semaphore.h>

//封装信号类
class sem
{
private:
    sem_t m_sem;
public:
    sem(){
        if( sem_init( &m_sem, 0, 0 ) != 0 ){
            throw std::exception();
        }
    }
    sem(int num)
    {
        if (sem_init(&m_sem, 0, num) != 0)
        {
            throw std::exception();
        }
    }
    ~sem(){
        sem_destroy( &m_sem );
    }
    //P -1
    bool wait(){
        return sem_wait( &m_sem ) == 0;
    }
    //V +1
    bool post(){
        return sem_post( &m_sem ) == 0;
    }
};
//封装互斥锁
class locker
{
private:
    pthread_mutex_t m_mutex;
public:
    locker(){
        if( pthread_mutex_init( &m_mutex, NULL ) != 0){
            throw std::exception();
        }
    };
    ~locker(){
        pthread_mutex_destroy( &m_mutex );
    };
    bool lock(){
        return pthread_mutex_lock( &m_mutex ) == 0;
    }
    bool unlock(){
        return pthread_mutex_unlock( &m_mutex ) == 0;
    }
    pthread_mutex_t *get()
    {
        return &m_mutex;
    }
};
//封装条件变量
class cond{
private:
    //pthread_mutex_t m_mutex;
    pthread_cond_t m_cond;
public:
    cond(){
        /*
        if( pthread_mutex_init( &m_mutex, NULL ) != 0 ){
            throw std::exception();
        }
        */
        if( pthread_cond_init( &m_cond, NULL) != 0 ){
            //pthread_mutex_destroy( &m_mutex );
            throw std::exception();
        }
    }
    ~cond(){
        //pthread_mutex_destroy( &m_mutex );
        pthread_cond_destroy( &m_cond );
    }
    
    bool wait(pthread_mutex_t* m_mutex)
    {
        int ret = 0;
        //pthread_mutex_lock(&m_mutex);
        ret = pthread_cond_wait(&m_cond, m_mutex);
        //pthread_mutex_unlock(&m_mutex);
        return ret == 0;
    }

    bool timewait(pthread_mutex_t* m_mutex, struct timespec t ){
        
        int ret = 0;
        //pthread_mutex_lock( &m_mutex );
        ret = pthread_cond_timedwait( &m_cond, m_mutex, &t );
        //pthread_mutex_unlock( &m_mutex );
        return ret == 0;
    }
    //唤醒一个等待目标条件变量的线程，谁被唤醒取决于线程调度
    bool signal(){
        return pthread_cond_signal( &m_cond ) == 0;
    }
    //唤醒所有等待目标条件变量的线程
    bool broadcast()
    {
        return pthread_cond_broadcast(&m_cond) == 0;
    }

};

#endif

